package controllers

import (
	"fmt"
	"github.com/golang/glog"
	"net/http"
	"strconv"
	"sync"
	"time"
)

func NoticeTask(w http.ResponseWriter, r *http.Request) {
	// 构造通知任务列表
	var tasks []Task
	for i := 1; i <= 10; i++ {
		var users []User
		for j := i * 10; j <= (i*10 + 2); j++ { // j作为用户id，每批2个用户
			user := User{j, "user_" + strconv.Itoa(j)}
			users = append(users, user)
		}
		task := Task{i, users}
		tasks = append(tasks, task)
	}

	// for-range 一个任务列表（3个），并通过goroutine和userCh生产任务
	userCh := make(chan User, 10)
	wgProducer := new(sync.WaitGroup)
	wgConsumer := new(sync.WaitGroup)

	for _, task := range tasks {
		wgProducer.Add(1)
		go task.producer(wgProducer, userCh)
	}

	// 通过goroutine 并发消费和处理任务
	for i := 1; i <= 2; i++ {
		wgConsumer.Add(1)
		go consumer(wgConsumer, userCh)
	}

	wgProducer.Wait()
	close(userCh)
	wgConsumer.Wait()
}

type Task struct {
	id    int    // 任务id
	users []User // 该任务下的用户列表（通知目标）
}

type User struct {
	id   int
	name string
}

// 生产者，把需通知的用户id, 发送到用户通道 userCh
func (t Task) producer(wg *sync.WaitGroup, userCh chan User) {
	for _, user := range t.users {
		userCh <- user
		fmt.Printf("create notice task for user,task_id:%d, id: %d name:%s \n", t.id, user.id, user.name)
		glog.Infof("create notice task for user,task_id:%d, id: %d name:%s \n", t.id, user.id, user.name)
	}

	wg.Done()
}

// 消费者，从用户通道userCh接收到用户id，并通知
func consumer(wg *sync.WaitGroup, userCh chan User) {
	for user := range userCh {
		time.Sleep(time.Second)
		fmt.Printf("consumer, send message for user, id: %d, name:%s\n", user.id, user.name)
	}

	wg.Done()
}
